From: Arianna Avanzini Date: Sat, 30 Aug 2014 16:29:41 +0000 (+0200) Subject: xen/x86: factor out map and unmap from the memory_mapping DOMCTL X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~4488 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=276a9b6ea17644ebe6bf111ed365d8c3b765f10a;p=xen.git xen/x86: factor out map and unmap from the memory_mapping DOMCTL This commit factors out from the XEN_DOMCTL_memory_mapping hypercall implementation, currently available only for x86, the operations related to memory ranges map and unmap. The code is factored out into two {map|unmap}_mmio_regions() functions for x86, that will match the corresponding pair of ARM functions when the DOMCTL will be moved to common code in the following commit. This commit also adds an unmap_mmio_regions() function for ARM so that the following transition to common code is cleaner. Signed-off-by: Arianna Avanzini Acked-by: Ian Campbell Acked-by: Jan Beulich Acked-by: Julien Grall Cc: Dario Faggioli Cc: Paolo Valente Cc: Stefano Stabellini Cc: Keir Fraser Cc: Tim Deegan Cc: Ian Jackson Cc: Andrew Cooper Cc: Eric Trudeau Cc: Viktor Kleinik Cc: Andrii Tseglytskyi --- diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 05d83b14cb..c016450a2b 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -893,6 +893,18 @@ int map_mmio_regions(struct domain *d, MATTR_DEV, p2m_mmio_direct); } +int unmap_mmio_regions(struct domain *d, + unsigned long start_gfn, + unsigned long nr_mfns, + unsigned long mfn) +{ + return apply_p2m_changes(d, REMOVE, + pfn_to_paddr(start_gfn), + pfn_to_paddr(start_gfn + nr_mfns), + pfn_to_paddr(mfn), + MATTR_DEV, p2m_invalid); +} + int guest_physmap_add_entry(struct domain *d, unsigned long gpfn, unsigned long mfn, diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 9cdbc3dae4..caa3be61cb 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -670,17 +670,14 @@ long arch_do_domctl( d->domain_id, gfn, mfn, nr_mfns); ret = iomem_permit_access(d, mfn, mfn_end); - if ( !ret && paging_mode_translate(d) ) + if ( !ret ) { - for ( i = 0; !ret && i < nr_mfns; i++ ) - ret = set_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i)); + ret = map_mmio_regions(d, gfn, nr_mfns, mfn); if ( ret ) { printk(XENLOG_G_WARNING - "memory_map:fail: dom%d gfn=%lx mfn=%lx ret:%ld\n", - d->domain_id, gfn + i, mfn + i, ret); - while ( i-- ) - clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i)); + "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n", + d->domain_id, gfn, mfn, nr_mfns, ret); if ( iomem_deny_access(d, mfn, mfn_end) && is_hardware_domain(current->domain) ) printk(XENLOG_ERR @@ -697,13 +694,7 @@ long arch_do_domctl( "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n", d->domain_id, gfn, mfn, nr_mfns); - if ( paging_mode_translate(d) ) - for ( i = 0; i < nr_mfns; i++ ) - { - ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i)); - if ( ret ) - rc = ret; - } + rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn); ret = iomem_deny_access(d, mfn, mfn_end); if ( !ret ) ret = rc; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 2586a3cbbc..32776c32c7 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1725,6 +1725,51 @@ unsigned long paging_gva_to_gfn(struct vcpu *v, return hostmode->gva_to_gfn(v, hostp2m, va, pfec); } +int map_mmio_regions(struct domain *d, + unsigned long start_gfn, + unsigned long nr, + unsigned long mfn) +{ + int ret = 0; + unsigned long i; + + if ( !paging_mode_translate(d) ) + return 0; + + for ( i = 0; !ret && i < nr; i++ ) + { + ret = set_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i)); + if ( ret ) + { + unmap_mmio_regions(d, start_gfn, i, mfn); + break; + } + } + + return ret; +} + +int unmap_mmio_regions(struct domain *d, + unsigned long start_gfn, + unsigned long nr, + unsigned long mfn) +{ + int err = 0; + unsigned long i; + + if ( !paging_mode_translate(d) ) + return 0; + + for ( i = 0; i < nr; i++ ) + { + int ret = clear_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i)); + if ( ret ) + err = ret; + } + + return err; +} + /*** Audit ***/ #if P2M_AUDIT diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index 13fea364ed..648144f2af 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -108,6 +108,10 @@ int map_mmio_regions(struct domain *d, unsigned long start_gfn, unsigned long nr_mfns, unsigned long mfn); +int unmap_mmio_regions(struct domain *d, + unsigned long start_gfn, + unsigned long nr_mfns, + unsigned long mfn); int guest_physmap_add_entry(struct domain *d, unsigned long gfn, diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index d19f50ced9..2a128ed1ea 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -32,6 +32,18 @@ #include #include /* for pagetable_t */ +/* Map MMIO regions in the p2m: start_gfn and nr describe the range in + * the guest physical address space to map, starting from the machine + * frame number mfn. */ +int map_mmio_regions(struct domain *d, + unsigned long start_gfn, + unsigned long nr, + unsigned long mfn); +int unmap_mmio_regions(struct domain *d, + unsigned long start_gfn, + unsigned long nr, + unsigned long mfn); + extern bool_t opt_hap_1gb, opt_hap_2mb; /*